package jtwittconsolepackage;

import jTwittConsoleExceptions.IJTwittConsoleErrorTypes;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;


/**
 * Class logs error messages. There should be only one ErrorLogger (singleton).
 * Every class has its own error code.
 * Error codes are four-digit numbers. The first number describes the class.
 * The other numbers the position within the class.
 * CenterApplication:   1xxx
 * ConfigReader:        2xxx
 * 
 * Concrete error numbers are defined in {@link IJTwittConsoleErrorTypes}
 */
public class ErrorLogger
{
    private final String errorFilePath = "./errorLog";
    private File errorFile;
    private static ErrorLogger errorLoggerInstance = null;

    private ErrorLogger()
    {
        errorFile = new File(errorFilePath);

        //if the file does not exist already
        if(!errorFile.exists())
        {
            try
            {
                errorFile.createNewFile();
            }
            catch (IOException ex)
            {
               System.out.println("An error occured: Could not generate log file");
               System.out.println(ex.getMessage());
               ex.printStackTrace();
            }

            System.out.println("log file created");
        }
    }

    public static ErrorLogger getInstance()
    {
        if(errorLoggerInstance == null)
        {
            errorLoggerInstance = new ErrorLogger();
        }

        return errorLoggerInstance;
    }

    /**
     * Writes the error message to the log file.
     * @param text The error message which should be logged.
     */
    private void logError(String text)
    {
        try
        {
            BufferedWriter out
                    = new BufferedWriter(new FileWriter(errorFilePath, true));
            out.newLine();
            out.write(DateUtils.now("yyyy.MM.dd G 'at' hh:mm:ss z") + " -> ");
            out.write(text);
            out.flush();
        }
        catch(IOException ioe)
        {
            System.out.println("An error occured while writing to the log file");
            System.out.println(ioe.getMessage());
            ioe.printStackTrace();
        }
    }
    
    /**
     * Method is called when an exception occurs - everything else happens here.
     * @param errorMsgForUser the message that is displayed to user
     * @param twitterApiExceptionNumber the number of the exception - number is
     *          defined by the twitter api - use "-1" if there is no number
     *          (user defined error)
     * @param e the exception that has to be logged
     * @param internalErrorString the number that is defined through
     *          jTwittConsole for the specific error
     */
    public void exceptionOccured(String errorMsgForUser,
                                 String twitterApiExceptionNumber,
                                 Exception e,
                                 String internalErrorString)
    {
        System.out.println(errorMsgForUser);
        ErrorLogger.getInstance().logError(internalErrorString);

        if (!twitterApiExceptionNumber.equals("-1"))
        {
            ErrorLogger.getInstance().logError(twitterApiExceptionNumber);
        }

        ErrorLogger.getInstance().logError(e.toString());

        if (e.getMessage() != null)
        {
            ErrorLogger.getInstance().logError(e.getMessage());
        }
        else
        {
            ErrorLogger.getInstance().logError("Message of exception is null");
        }

        if (e.getCause() != null)
        {
            ErrorLogger.getInstance().logError(e.getCause().toString());
        }
        else
        {
            ErrorLogger.getInstance().logError("No cause for exception available");
        }

        if (e.getStackTrace() != null)
        {
            for (StackTraceElement stackTraceElement : e.getStackTrace())
            {
                ErrorLogger.getInstance().logError(stackTraceElement.toString());
            }
        }
        else
        {
            ErrorLogger.getInstance().logError("StackTrace of exception is null");
        }
    }
    
    /**
     * Exception logging method especially for errors that occur reading a key
     * from config file;
     * @param errorMsgForUser the message that is displayed to user
     * @param twitterApiExceptionNumber the number of the exception - number is 
     *          defined by the twitter api - use "-1" if there is no number
     *          (user defined error)
     * @param e the exception that has to be logged
     * @param internalErrorString the number that is defined through
     *          jTwittConsole for the specific error
     * @param keyToRead the key that has to be read
     */
    public void exceptionOccured(String errorMsgForUser,
            String twitterApiExceptionNumber,
            Exception e,
            String internalErrorString,
            String keyToRead)
    {
    	this.exceptionOccured(errorMsgForUser, twitterApiExceptionNumber, e,
                internalErrorString);
    	ErrorLogger.getInstance().logError("Key to read: " + keyToRead );
    }
}
